package linkedList;

//双向链表
public class DoubleLinkedList {
    public static void main(String[] args) {
        //测试
        HeroNode2 heroNode1 = new HeroNode2(1, "宋江", "及时雨");
        HeroNode2 heroNode2 = new HeroNode2(2, "卢俊义", "玉麒麟");
        HeroNode2 heroNode3 = new HeroNode2(3, "吴用", "智多星");
        DoubleLinkedListDemo doubleLinkedListDemo = new DoubleLinkedListDemo();
        doubleLinkedListDemo.add(heroNode1);
        doubleLinkedListDemo.add(heroNode2);
        doubleLinkedListDemo.add(heroNode3);
        //doubleLinkedListDemo.del(2);
        doubleLinkedListDemo.undate(new HeroNode2(1, "晁盖", "天王"));
        doubleLinkedListDemo.list();
        System.out.println("双向链表反转");
        doubleLinkedListDemo.reverse(doubleLinkedListDemo.head);
        doubleLinkedListDemo.list();
    }

    //定义链表
    static class DoubleLinkedListDemo {
        //建立头节点
        private HeroNode2 head = new HeroNode2(0, "", "");

        //返回头节点
        public HeroNode2 getHead() {
            return head;
        }

        //遍历双向链表
        public void list() {
            if (head.next == null) {
                System.out.println("链表为空");
                return;
            }
            //头节点不能动
            HeroNode2 temp = head.next;
            //遍历找到最后一个节点
            while (true) {
                System.out.println(temp);
                if (temp.next == null) {
                    break;
                }
                temp = temp.next;
            }
        }

        //添加节点
        public void add(HeroNode2 node) {
            //头节点不能动
            HeroNode2 temp = head;
            //遍历找到最后一个节点
            while (true) {
                if (temp.next == null) {
                    break;
                }
                temp = temp.next;
            }
            //指向新的节点
            temp.next = node;
            node.pre = temp;
        }

        //删除节点
        public void del(int no) {
            //头节点不能动
            HeroNode2 temp = head;
            if (temp.next == null) {
                System.out.println("链表为空");
            }
            boolean flag = false;
            //遍历
            while (true) {
                if (temp.next == null) {
                    break;
                }
                if (temp.no == no) {
                    flag = true;
                    break;
                }
                temp = temp.next;
            }
            if (flag) {
                //被删除的节点，没有引用后会被gc清理。
                temp.pre.next = temp.next;
                if (temp.next != null) {
                    temp.next.pre = temp.pre;
                }
            } else {
                System.out.printf("没有找到排名为%d的好汉,无法删除。" + '\n', no);
            }

        }

        //修改节点
        public void undate(HeroNode2 node) {
            //头节点不能动
            HeroNode2 temp = head;
            if (temp == null) {
                System.out.println("链表为空");
            }
            boolean flag = false;
            //遍历
            while (true) {
                if (temp.no == node.no) {
                    flag = true;
                    break;
                }
                if (temp.next == null) {
                    break;
                }
                temp = temp.next;
            }
            if (flag) {
                temp.name = node.name;
                temp.nickname = node.nickname;
            } else {
                System.out.printf("没有找到排名为%d的好汉，无法修改。" + '\n', node.no);
            }
        }

        //双链表反转
        public void reverse(HeroNode2 head) {
            if (head.next == null || head.next.next == null) {
                return;
            }
            HeroNode2 cur = head.next;
            HeroNode2 node = null;
            /*HeroNode2 reverseNode = null;
            while (cur != null) {
                node = new HeroNode2(cur.no, cur.name, cur.nickname);
                node.pre = null;
                node.next = reverseNode;
                reverseNode = node;
                cur = cur.next;
            }
            head.next = reverseNode;
            //再设置一遍pre
            cur = head.next;
            node = null;
            while (cur != null){
                if (node != null){
                    cur.pre = node;
                }
                node = cur;
                cur = cur.next;
            }*/
            while (cur != null) {
                HeroNode2 next = cur.next;
                cur.next = node;
                cur.pre = next;
                node = cur;
                cur = next;
            }
            head.next = node;
        }
    }


    //定义节点
    static class HeroNode2 {
        private int no;//排名
        private String name;//名字
        private String nickname;//名号
        private HeroNode2 next;//指向下一个节点
        private HeroNode2 pre;//指向上一个节点

        public HeroNode2(int hno, String hname, String hnickname) {
            this.no = hno;
            this.name = hname;
            this.nickname = hnickname;
        }

        @Override
        public String toString() {
            return "HeroNode{" +
                    "no=" + no +
                    ", name='" + name + '\'' +
                    ", nickname='" + nickname + '\'' +
                    '}';
        }
    }
}
